/*
 * OREKIT-X
 * Copyright 2002-2008 CS Communication & Systemes
 * 
 * Parts of this software package have been licensed to CS
 * Communication & Systemes (CS) under one or more contributor license
 * agreements.  See the NOTICE file distributed with this work for
 * additional information.
 *  
 * This is an experimental copy of OREKIT from www.orekit.org.
 * Please use the original OREKIT from orekit.org for normal work
 * unrelated to this research project.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License.  You
 * may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.  See the License for the specific language governing
 * permissions and limitations under the License.
 */
package ore.forces.gravity.potential;

import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

import ore.io.DataProvidersManager;
import ore.errors.OrekitException;

/**
 * Factory used to read gravity potential files in several supported formats.
 * 
 * @author Fabien Maussion
 */
public class PotentialReaderFactory {


    private final List<PotentialCoefficientsReader> readers;

    /** 
     * This constructor uses default values for gravity potential file names
     * regular expressions: "^g(\\d)+_eigen_(\\w)+_coef$" for ICGEM files,
     * "^eigen[-_](\\w)+_coef$" for SHM files and "^egm\\d\\d_to\\d.*$" for
     * EGM files.
     */
    public PotentialReaderFactory() {
        super();
        this.readers = new ArrayList<PotentialCoefficientsReader>();
        this.readers.add(new ICGEMFormatReader("^g(\\d)+_eigen_(\\w)+_coef$"));
        this.readers.add(new SHMFormatReader("^eigen[-_](\\w)+_coef$"));
        this.readers.add(new EGMFormatReader("^egm\\d\\d_to\\d.*$"));
    }

    /** 
     * @param icgemficNames Regular expression for ICGEM (Eigen)
     * gravity potential files.  If null, ICGEM files reader will not
     * be set up
     * @param shmficNames Regular expression for SHM (Eigen) gravity
     * potential files.  If null, SHM files reader will not be set up
     * @param egmficNames Regular expression for EGM gravity potential
     * files.  If null, EGM files reader will not be set up
     */
    public PotentialReaderFactory(String icgemficNames, String shmficNames,
                                  String egmficNames)
    {
        super();
        this.readers = new ArrayList<PotentialCoefficientsReader>();
        if (icgemficNames != null) {
            this.readers.add(new ICGEMFormatReader(icgemficNames));
        }
        if (shmficNames != null) {
            this.readers.add(new SHMFormatReader(shmficNames));
        }
        if (egmficNames != null) {
            this.readers.add(new EGMFormatReader(egmficNames));
        }
    }

    /** 
     * @param reader the reader to add
     */
    public void addPotentialReader(final PotentialCoefficientsReader reader) {
        this.readers.add(reader);
    }

    /** 
     * Get the gravity potential coefficients provider from the first supported file.
     * 
     * @return a gravity potential coefficients provider containing loaded data
     * 
     * @exception IOException Data can't be read
     * @exception ParseException Data can't be parsed
     * @exception OrekitException Data is missing, or loader specific
     * error 
     */
    public PotentialCoefficientsProvider getPotentialProvider()
        throws IOException, ParseException, OrekitException
    {
        /*
         * Test the available readers
         */
        for (PotentialCoefficientsReader reader : readers) {
            DataProvidersManager.getInstance().feed(reader.getSupportedNames(), reader);
            if (!reader.stillAcceptsData()) {
                return reader;
            }
        }
        throw new OrekitException("no gravity potential data loaded");
    }

}
